package cn.jaye.fabric.domain.service;

import cn.jaye.fabric.common.constant.Global;
import cn.jaye.fabric.common.constant.MicroConstant;
import cn.jaye.fabric.common.model.ResultBody;
import cn.jaye.fabric.common.util.AESUtil;
import cn.jaye.fabric.common.util.KeyUtil;
import cn.jaye.fabric.common.util.MD5Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @author Jaye
 * @create 2017-12-21 13:36
 */
@Service
public class RestTemplateService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MicroConstant microConstant;

    public JSONObject getUrlResponse(String url, JSONObject postData) {
        System.out.println("請求的URL:" + url);
        if (getEncryptState()) {
            return encryptRequest(url, postData);
        }
        return noEncryptRequest(url, postData);
    }

    private JSONObject setInputData(Object data) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("data", data);
        return jsonObject;
    }

    private HttpHeaders setHeaders(HttpHeaders httpHeaders, String data) {
        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
        httpHeaders.setContentType(type);
        httpHeaders.add("Accept", MediaType.APPLICATION_JSON.toString());
        long timestamp = System.currentTimeMillis() - 10000;
        String nonce = KeyUtil.getRandomString(16);
        String channel = microConstant.getDefaultChannel();
        httpHeaders.set("x-hna-tenant", microConstant.getDefaultAccesspointId());
        httpHeaders.set("x-hna-timestamp", String.valueOf(timestamp));
        httpHeaders.set("x-hna-nonce", nonce);
        httpHeaders.set("x-hna-channel", channel);
        httpHeaders.set("username", Global.TEST_USERNAME);
        httpHeaders.set("password", Global.TEST_PASSWORD);
        httpHeaders.set("orgid", Global.TEST_ORGID);
        httpHeaders.set("x-hna-sign", sign(microConstant.getDefaultAccesspointSignKey(), data, microConstant.getDefaultAccesspointId(), channel, nonce, String.valueOf(timestamp)));
        return httpHeaders;
    }

    private String sign(String... parms) {
        String signature = "";
        String str = "";
        for (String s : parms) {
            if (StringUtils.isNotBlank(s)) {
                str += s;
            }
        }
        try {
            signature = MD5Util.MD5(str);
        } catch (Exception e) {
            signature = "";
        }
        return signature;
    }

    private boolean getEncryptState() {
        if (microConstant.getHttpEncryptFlag()) {
            return true;
        }
        return false;
    }

    private JSONObject encryptRequest(String url, JSONObject postData) {
        String reqData = JSON.toJSONString(postData, SerializerFeature.DisableCircularReferenceDetect);
        try {
            reqData = AESUtil.encrypt(reqData, microConstant.getDefaultAccesspointAesKey(), microConstant.getDefaultAccesspointAesIv());
        } catch (Exception e) {
            System.out.println("加密失敗");
        }
        HttpEntity<JSONObject> entity = new HttpEntity<>(setInputData(reqData), setHeaders(new HttpHeaders(), reqData));
        HttpEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        System.out.println("------調用返回結果:-------");
        System.out.println(responseEntity.getBody());
        System.out.println("-------------------------");
        JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
        if (StringUtils.isNotBlank(jsonObject.getString("data"))) {
            String deCodeData = "";
            try {
                deCodeData = AESUtil.decrypt(jsonObject.getString("data"), microConstant.getDefaultAccesspointAesKey(), microConstant.getDefaultAccesspointAesIv());
            } catch (Exception e) {
                System.out.println("The response body decrypt has error");
            }
            if (deCodeData.startsWith("[") && deCodeData.endsWith("]")) {
                jsonObject.put("data", JSONArray.parseArray(deCodeData));
            } else {
                jsonObject.put("data", JSONObject.parseObject(deCodeData));
            }
        }
        return jsonObject;
    }

    private ResultBody encryptRequeste(String url, JSONObject postData) {
        String reqData = JSON.toJSONString(postData, SerializerFeature.DisableCircularReferenceDetect);
        try {
            reqData = AESUtil.encrypt(reqData, microConstant.getDefaultAccesspointAesKey(), microConstant.getDefaultAccesspointAesIv());
        } catch (Exception e) {
            System.out.println("加密失敗");
        }
        HttpEntity<JSONObject> entity = new HttpEntity<>(setInputData(reqData), setHeaders(new HttpHeaders(), reqData));
        HttpEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        System.out.println("------調用返回結果:-------");
        System.out.println(responseEntity.getBody());
        System.out.println("-------------------------");
        ResultBody resultBody = JSON.parseObject(responseEntity.getBody(), ResultBody.class);
        JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
        if (StringUtils.isNotBlank(jsonObject.getString("data"))) {
            String deCodeData = "";
            try {
                deCodeData = AESUtil.decrypt((String) resultBody.getData(), microConstant.getDefaultAccesspointAesKey(), microConstant.getDefaultAccesspointAesIv());
            } catch (Exception e) {
                System.out.println("The response body decrypt has error");
            }
            resultBody.setData(deCodeData);
            jsonObject.put("data", deCodeData);
        }
        return resultBody;
    }

    private JSONObject noEncryptRequest(String url, JSONObject postData) {
        HttpEntity<JSONObject> entity = new HttpEntity<>(setInputData(postData), setHeaders(new HttpHeaders(), "{}"));
        HttpEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
        System.out.println("------調用返回結果:-------");
        System.out.println(responseEntity.getBody());
        System.out.println("-------------------------");
        JSONObject jsonObject = JSONObject.parseObject(responseEntity.getBody());
        return jsonObject;
    }
}
